﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using ShineTech.Domain.Models.Kanbans;
using ShineTech.Domain.SeedWork;

namespace ShineTech.Infrastructure.Repositories.Kanbans
{
    public class KanbanRepository : IKanbanRepository
    {
        private readonly RentalContext _context;
        public KanbanRepository(RentalContext context)
        {
            _context = context ?? throw CustomException.NullArgument(nameof(context));
        }
        public void Add(Kanban entity)
        {
            _context.Kanbans.Add(entity);
        }

        public async Task<IEnumerable<Kanban>> FindAllAsync(ISpecification<Kanban> specification)
        {
            var query = specification.Includes
                .Aggregate(_context.Set<Kanban>().AsQueryable(), (current, include) => current.Include(include));
            query = query.Where(specification.Expression).AsNoTracking();

            var stringSql = query.ToSql();
            Console.WriteLine(stringSql);
            return await query.ToListAsync();
        }

        public async Task<PageData<Kanban>> GetPageData(ISpecification<Kanban> specification, int pageIndex, int pageSize)
        {
            pageIndex = pageIndex < 1 ? 1 : pageIndex;
            var query = specification.Includes
                .Aggregate(_context.Set<Kanban>().AsQueryable(), (current, include) => current.Include(include));

            query = query.Where(specification.Expression).AsNoTracking();
            var totalCount = await query.CountAsync();
            var list = await query.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync();

            var pageData = list.ToPageDataList(pageIndex, pageSize, totalCount);
            return pageData;

        }

        public async Task<Kanban> FindOneAsync(ISpecification<Kanban> specification)
        {
            var query = specification.Includes
                .Aggregate(_context.Set<Kanban>().AsQueryable(), (current, include) => current.Include(include));
            return await query.FirstOrDefaultAsync(specification.Expression);
        }

        public void Remove(Kanban entity)
        {
            _context.Kanbans.Remove(entity);
        }

        public void Update(Kanban entity)
        {
            _context.Kanbans.Update(entity);
        }
    }
}
